package main

import (
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric-chaincode-go/shim"
	"github.com/hyperledger/fabric-protos-go/peer"
	"github.com/op/go-logging"
	"os"
)

type Chaincode struct {
}

var proofInfo = ProofInfo{}

type ProofInfo struct {
	FileName   string `json:"file_name"`
	FileHash   string `json:"file_hash"`
	FileType   string `json:"file_type"`
	UploadUser string `json:"upload_user"`
	FileSize   string `json:"file_size"`
	UploadDate string `json:"upload_date"`
}

var Mylogger = logging.MustGetLogger("Chaincode")

func init() {
	format := logging.MustStringFormatter("%{shortfile} %{time:15:04:05.000} [%{module}] %{level:.4s} : %{message}")
	backend := logging.NewLogBackend(os.Stderr, "", 0)
	backendFormatter := logging.NewBackendFormatter(backend, format)

	logging.SetBackend(backendFormatter).SetLevel(logging.DEBUG, "Chaincode")
}
func (t *Chaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
	Mylogger.Debug("Init Chaincode...")
	return shim.Success([]byte("SUCCESS"))
}

func (t *Chaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	function, args := stub.GetFunctionAndParameters()
	Mylogger.Debugf("Invoke function=%v,args=%v\n", function, args)
	if len(args) < 1 || len(args[0]) == 0 {
		err := fmt.Sprintf("the invoke args length < 1 or arg[0] is empty")
		Mylogger.Error(err)
		return shim.Error(err)
	}
	switch function {
	case "DataUpload":
		return t.DataUpload(stub, args)
	case "DataVerification":
		return t.DataVerification(stub, args)
	}
	return shim.Error("指定的函数名称错误")

}
func (t *Chaincode) DataUpload(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	if len(args) < 2 || len(args[0]) == 0 {
		return shim.Error(fmt.Sprintf("DataUpload err: invalid param(%v)", args))
	}

	if err := json.Unmarshal([]byte(args[0]), &proofInfo); err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal ProofInfo err: %v", err))
	}
	//proofInfo.TX_HASH = stub.GetTxID()
	putData, err := json.Marshal(proofInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Marshal ProofInfo err: %v", err))
	}
	if err := stub.PutState(proofInfo.FileHash, putData); err != nil {
		return shim.Error(fmt.Sprintf("DataUpload err: %v", err))
	}
	return shim.Success([]byte("success!"))
}
func (t *Chaincode) DataVerification(stub shim.ChaincodeStubInterface, args []string) peer.Response {
	Mylogger.Debugf("DataVerification by id: %s\n", args[0])

	res, err := stub.GetState(args[0])
	if err != nil {
		return shim.Error(fmt.Sprintf("failed to DataVerification err: %v", err))
	}

	if res == nil {
		return shim.Error("no result")
	}
	if err := json.Unmarshal(res, &proofInfo); err != nil {
		return shim.Error(fmt.Sprintf("failed to Unmarshal ProofInfo err: %v", err))

	}
	return shim.Success(res)
}
func main() {
	err := shim.Start(new(Chaincode))
	if err != nil {
		Mylogger.Errorf("Error starting chaincode: %s", err)
	}
}
